package com.qiudao.basestudy.util.mybatisPlugin;

/**
 * Description:
 *
 * @Author: liuhuan
 * @Date: 2019-03-15  14:23
 * @Version 1.0
 */

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Description: LombokPlugin
 * addStaticPropertyName, addPropertyComment, addPropertySwaggerAnnotation
 * @author: gdc
 * @date: 2020/3/21
 * @version 1.0
 */
public class LombokPlugin extends PluginAdapter {

    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    /**
     * 拦截 普通字段
     */
    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        addCustomCode(topLevelClass, introspectedTable);
        return true;
    }

    /**
     * 拦截 主键
     */
    @Override
    public boolean modelPrimaryKeyClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        addCustomCode(topLevelClass, introspectedTable);
        return true;
    }

    /**
     * 拦截 blob 类型字段
     */
    @Override
    public boolean modelRecordWithBLOBsClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        addCustomCode(topLevelClass, introspectedTable);
        return true;
    }

    /**
     * Model增加注解
     */
    private void addCustomCode(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        //添加依赖
        topLevelClass.addImportedType("lombok.Data");
        topLevelClass.addImportedType("lombok.NoArgsConstructor");
        topLevelClass.addImportedType("lombok.AllArgsConstructor");
        topLevelClass.addImportedType("lombok.experimental.Accessors");
        topLevelClass.addImportedType("io.swagger.annotations.ApiModel");

        //注解
        topLevelClass.addAnnotation("@Data");
        topLevelClass.addAnnotation("@NoArgsConstructor");
        topLevelClass.addAnnotation("@AllArgsConstructor");
        topLevelClass.addAnnotation("@Accessors(chain = true)");
        topLevelClass.addAnnotation("@ApiModel(value = \"\")");

        String addStaticPropertyName = this.properties.getProperty("addStaticPropertyName");
        if ("true".equals(addStaticPropertyName)) {
            //添加字名段静变量
            addStaticPropertyName(topLevelClass, introspectedTable);
        }
    }

    private void addStaticPropertyName(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        for (IntrospectedColumn introspectedColumn : introspectedTable.getAllColumns()) {
            {
                String javaProperty = introspectedColumn.getJavaProperty();
                Field field = new Field();
                field.setName(javaProperty.toUpperCase());
                field.setVisibility(JavaVisibility.PUBLIC);
                field.setInitializationString("\"" + javaProperty + "\"");
                field.setFinal(true);
                field.setStatic(true);
                field.setType(new FullyQualifiedJavaType("String"));
                topLevelClass.addField(field);
            }
            {
                String actualColumnName = introspectedColumn.getActualColumnName();
                Field field = new Field();
                field.setName("DB_" + actualColumnName.toUpperCase());
                field.setVisibility(JavaVisibility.PUBLIC);
                field.setInitializationString("\"" + actualColumnName + "\"");
                field.setFinal(true);
                field.setStatic(true);
                field.setType(new FullyQualifiedJavaType("String"));
                topLevelClass.addField(field);
            }
        }
    }

    /**
     * 属性上是否添加注释
     *
     * @param field
     * @param topLevelClass
     * @param introspectedColumn
     * @param introspectedTable
     * @param modelClassType
     * @return
     */
    @Override
    public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        comment(field, topLevelClass, introspectedTable, introspectedColumn);
        return true;
    }

    //Model属性上面的注释
    private void comment(JavaElement element, TopLevelClass topLevelClass, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        element.getJavaDocLines().clear();
        // 此处用于添加注释
        /*String addPropertyComment = this.properties.getProperty("addPropertyComment");
        if ("true".equals(addPropertyComment)) {
            String remark = introspectedColumn.getRemarks();
            if (remark != null && remark.length() > 1) {
                element.addJavaDocLine("//" + remark);
            }
        }*/

        // 此处用于添加 Swagger 注解
        String addPropertySwaggerAnnotation = this.properties.getProperty("addPropertySwaggerAnnotation");
        if ("true".equals(addPropertySwaggerAnnotation)) {
            String remark = introspectedColumn.getRemarks();
            topLevelClass.addImportedType("io.swagger.annotations.ApiModelProperty");
            if (remark != null && remark.length() > 1) {
                element.addJavaDocLine("@ApiModelProperty(value=\"" + remark + "\")");
            }
        }
    }

    /**
     * Getter 不生成
     */
    @Override
    public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass,
                                              IntrospectedColumn introspectedColumn,
                                              IntrospectedTable introspectedTable,
                                              ModelClassType modelClassType) {
        return false;
    }

    /**
     * Setter 不生成
     */
    @Override
    public boolean modelSetterMethodGenerated(Method method,
                                              TopLevelClass topLevelClass,
                                              IntrospectedColumn introspectedColumn,
                                              IntrospectedTable introspectedTable,
                                              ModelClassType modelClassType) {
        return false;
    }


    //生成Base_Column_List
    @Override
    public boolean sqlMapBaseColumnListElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return true;
    }

    @Override
    public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
        if (false) {
            document.getRootElement().addElement(new TextElement(""));
            document.getRootElement().addElement(new TextElement("<!-- ### 以上代码由 custom-generator自动生成, 生成时间: " + (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()) + " ### -->\n\n\n"));
            document.getRootElement().addElement(new TextElement("<!-- Your codes goes here!!! -->"));
            document.getRootElement().addElement(new TextElement(""));
        }
        return true;
    }

    //生成mapper.java 接口方法
    @Override
    public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        addMapperClassAnnotation(interfaze);
        return true;
    }

    //添加@Component注解
    private void addMapperClassAnnotation(Interface interfaze) {
        String addPropertySwaggerAnnotation = this.properties.getProperty("addMapperClassComponentAnnotation");
        if ("true".equals(addPropertySwaggerAnnotation)) {
            interfaze.addImportedType(new FullyQualifiedJavaType("org.springframework.stereotype.Component"));
            //添加domain的注解
            interfaze.addAnnotation("@Component");
        }
    }
}